package com.gee.spring.cloud.data.transform.core.center.config.handler;

import com.gee.spring.cloud.common.core.api.result.ApiResult;
import com.gee.spring.cloud.common.core.entity.center.config.SatelliteMapping;
import com.gee.spring.cloud.common.starter.config.event.CenterConfigEventHandler;
import com.gee.spring.cloud.common.starter.feign.center.config.SatelliteMappingClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;

import static cn.hutool.core.text.StrPool.UNDERLINE;

/**
 * @author gepengjun
 * @since 2024/3/19 14:31
 */
@Component
@Slf4j
public class SatelliteMappingHandler extends CenterConfigEventHandler<SatelliteMapping> {

    //key: orgId_mappingSateId
    private final ConcurrentHashMap<String, SatelliteMapping> satelliteMappingMap = new ConcurrentHashMap<>();

    @Autowired
    private SatelliteMappingClient satelliteMappingClient;

    public SatelliteMapping getByOrgIdAndMappingSateId(Long orgId, Long mappingSateId) {
        String key = buildKey(orgId, mappingSateId);
        return satelliteMappingMap.computeIfAbsent(key, newKey -> satelliteMappingClient.getByOrgIdAndSateId(orgId, mappingSateId).getData());
    }

    @Override
    public void handlerUpdate(List<SatelliteMapping> dataList, List<SatelliteMapping> oldList) {
        dataList.forEach(satelliteMapping ->{
            String key = buildKey(satelliteMapping.getOrgId(), satelliteMapping.getSateId());
            satelliteMappingMap.computeIfPresent(key, (oldKey, old) -> satelliteMapping);
        });
    }

    @Override
    public void handlerDelete(List<SatelliteMapping> oldList) {
        oldList.forEach(satelliteMapping -> {
            String key = buildKey(satelliteMapping.getOrgId(), satelliteMapping.getSateId());
            satelliteMappingMap.remove(key);
        });
    }

    private static String buildKey(Long orgId, Long mappingDevId){
        return new StringJoiner(UNDERLINE).add(orgId.toString()).add(mappingDevId.toString()).toString();
    }


    public SatelliteMapping getByOrgIdAndMappingSateIdentity(long orgId, long mappingSateIdentity) {
        Optional<SatelliteMapping> satelliteMappingOptional = satelliteMappingMap.values().stream()
                .filter(satelliteMapping -> satelliteMapping.getMappingSateIdentity() == mappingSateIdentity)
                .findFirst();
        if (satelliteMappingOptional.isPresent()){
            return satelliteMappingOptional.get();
        }else {
            ApiResult<SatelliteMapping> satelliteMappingApiResult = satelliteMappingClient.getByOrgIdAndMappingSateIdentity(orgId, mappingSateIdentity);
            return getFromApiResult(satelliteMappingApiResult);
        }
    }

    public SatelliteMapping getByOrgIdAndSateCode(long orgId, String sateCode) {
        Optional<SatelliteMapping> satelliteMappingOptional = satelliteMappingMap.values().stream()
                .filter(deviceMapping -> sateCode.equals(deviceMapping.getMappingSateCode()))
                .findFirst();
        if (satelliteMappingOptional.isPresent()){
            return satelliteMappingOptional.get();
        }else {
            ApiResult<SatelliteMapping> satelliteMappingApiResult = satelliteMappingClient.getByOrgIdAndMappingSateCode(orgId, sateCode);
            return getFromApiResult(satelliteMappingApiResult);
        }
    }

    public SatelliteMapping getByOrgIdAndSateName(long orgId, String sateName) {
        Optional<SatelliteMapping> satelliteMappingOptional = satelliteMappingMap.values().stream()
                .filter(satelliteMapping -> sateName.equals(satelliteMapping.getMappingSateName()))
                .findFirst();
        if (satelliteMappingOptional.isPresent()){
            return satelliteMappingOptional.get();
        }else {
            ApiResult<SatelliteMapping> satelliteMappingApiResult = satelliteMappingClient.getByOrgIdAndMappingSateName(orgId, sateName);
            return getFromApiResult(satelliteMappingApiResult);
        }
    }

    private SatelliteMapping getFromApiResult(ApiResult<SatelliteMapping> satelliteMappingApiResult){
        SatelliteMapping satelliteMapping = satelliteMappingApiResult.getData();
        if (satelliteMappingApiResult.isSuccess() && satelliteMapping != null){
            String key = buildKey(satelliteMapping.getOrgId(), satelliteMapping.getSateId());
            satelliteMappingMap.put(key, satelliteMapping);
            return satelliteMapping;
        }else {
            return null;
        }
    }
}
